package com.orifine.orm.mysql;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.orifine.orm.Type;
import com.orifine.orm.TypeManager;
import com.orifine.orm.model.ColumnModel;
import com.orifine.orm.model.TableModel;


class MySqlStringBuffer {
	private List<String> sqlList = new ArrayList<String>();
	private StringBuffer out = new StringBuffer();
	
	public void createDatabase(String databaseName){
		out.append("CREATE DATABASE "+databaseName);
		semicolon().line();
	}
	
	public void dropDatabase(String databaseName) {
		out.append("DROP DATABASE "+databaseName);
		semicolon().line();
	}

	public void useDatabase(String databaseName) {
		out.append("USE "+databaseName);
		semicolon().line();
	}
	
	public void setForeignKeyChecks(boolean check){
		out.append("SET FOREIGN_KEY_CHECKS="+check);
		semicolon().line();
	}
	
	public void go(){
//		line();
//		out.append("GO");
//		semicolon();
	}
	
	public void createTable(TableModel tableModel) {
		doubleLine();
		create()._().table()._();
		out.append(tableModel.getName());
		left();
		
		{
			boolean isFirst = true;
			for(ColumnModel column : tableModel.getColumns()){
				if(!isFirst){
					comma().line().tab();
				} else {
					line().tab();
				}
				out.append(column.getName());
				_();
				out.append(column.getScriptType());
				isFirst = false;
				
				//NOT NULL
				if(column.getNotNull().getValue()){
					_().not()._().nul();
				}
				
				//DEFAULT
				if(column.getDefault() != null){
					_();
					out.append("DEFAULT ").append(TypeManager.getType(column.getDefault()).getScriptValue(column));
				}
				
				//Column UK
				if(column.getUnique().isUnique()){
					_();
					out.append("UNIQUE");
				}
				
				//AUTO INCREMENT
				if(column.isAutoIncrement() != null && column.isAutoIncrement()){
					_();
					out.append("AUTO_INCREMENT");
				}
				
				//Column PK
				if(column.getId().isId()){
					_();
					out.append("PRIMARY KEY");
				}
			}
		}
		
		//Table UK
		for(String uniqueColumnSetKey : tableModel.getUniqueColumnSets().keySet()){
			Set<ColumnModel> uniqueColumnSet = tableModel.getUniqueColumnSets().get(uniqueColumnSetKey);
			
			comma().line().tab();
			out.append("CONSTRAINT ").append("uk_").append(tableModel.getName()).append("_").append(uniqueColumnSetKey).append(" UNIQUE");
			left();
			boolean isFirst = true;
			for(ColumnModel uniqueColumn : uniqueColumnSet){
				if(isFirst){
					isFirst = false;
				} else {
					comma()._();
				}
				out.append(uniqueColumn.getName());
			}
			right();
		}
		
		//Table PK
		if(tableModel.getIdColumnSet().size() > 1){
			comma().line().tab();
			out.append("CONSTRAINT ").append("pk_").append(tableModel.getName()).append(" PRIMARY KEY");
			left();
			boolean isFirst = true;
			for(ColumnModel idColumn : tableModel.getIdColumnSet()){
				if(isFirst){
					isFirst = false;
				} else {
					comma()._();
				}
				out.append(idColumn.getName());
			}
			right();
		}
		
		//Table FK
		for(ColumnModel joinKeyColumn : tableModel.getColumns()){
			if(joinKeyColumn.getJoinColumn() != null){
				comma().line().tab();
				out.append("FOREIGN KEY");
				left();
				out.append(joinKeyColumn.getName());
				right();
				out.append(" REFERENCES ");
				out.append(joinKeyColumn.getJoinColumn().getTable().getName());
				left();
				out.append(joinKeyColumn.getJoinColumn().getName());
				right();
			}
		}
		
		line();
		right();
		semicolon();
	}
	
	public void insertInto(TableModel table, int infoSizeMax) {
		for(int i=0; i<(table.getInformationSize() < infoSizeMax?(table.getInformationSize() <= 0?infoSizeMax:table.getInformationSize()):infoSizeMax); i++){
			line();
			out.append("INSERT INTO ").append(table.getName());
			left();
			{
				boolean isFirst = true;
				for(ColumnModel column : table.getColumns() ){
					if(!isFirst){
						comma()._();
					}
					isFirst = false;
					
					out.append(column.getName());
				}
			}
			right();
			out.append(" VALUES");
			left();
			{
				boolean isFirst = true;
				for(ColumnModel column : table.getColumns()){
					if(!isFirst){
						comma()._();
					}
					isFirst = false;
					
					Object value = column.getInformation().value(i, column);
					Type type = TypeManager.getType(value);
					String outString = type.getScriptValue(column);
					
					out.append(outString);
				}
			}
			right().semicolon();
		}
	}

	public MySqlStringBuffer create() {
		out.append("CREATE");
		return this;
	}

	public MySqlStringBuffer table() {
		out.append("TABLE");
		return this;
	}

	public MySqlStringBuffer _() {
		out.append(" ");
		return this;
	}
	
	public MySqlStringBuffer left(){
		out.append("(");
		return this;
	}
	
	public MySqlStringBuffer right(){
		out.append(")");
		return this;
	}
	
	public MySqlStringBuffer comma(){
		out.append(",");
		return this;
	}
	
	public MySqlStringBuffer not(){
		out.append("NOT");
		return this;
	}
	
	public MySqlStringBuffer nul(){
		out.append("NULL");
		return this;
	}
	
	public MySqlStringBuffer tab(){
		out.append("\t");
		return this;
	}
	
	public MySqlStringBuffer line() {
		//out.append("\n");
		return this;
	}
	
	public MySqlStringBuffer doubleLine(){
		if(out.length() != 0) line().line();
		return this;
	}
	
	public MySqlStringBuffer semicolon(){
		//out.append(";");
		sqlList.add(out.toString());
		out = new StringBuffer();
		return this;
	}

	public List<String> getList(){
		return sqlList;
	}
}
